home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / dflat2.zip / DIALBOX.C < prev    next >
Text File  |  1991-04-12  |  13KB  |  572 lines

  1. /* ----------------- dialbox.c -------------- */
  2.  
  3. #include <string.h>
  4. #include <ctype.h>
  5. #include <stdlib.h>
  6. #ifdef MSC
  7. #include <direct.h>
  8. #else
  9. #include <dir.h>
  10. #endif
  11. #include <dos.h>
  12. #include <io.h>
  13. #include "dflat.h"
  14.  
  15. static int inFocusCommand(DBOX *);
  16. static void SetRadioButton(WINDOW, DBOX *, CTLWINDOW *);
  17. static void dbShortcutKeys(WINDOW, DBOX *, int);
  18. static int ControlProc(WINDOW, MESSAGE, PARAM, PARAM);
  19.  
  20. static int SysMenuOpen = FALSE;
  21.  
  22. int DialogProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  23. {
  24.     int rtn;
  25.     DBOX *db;
  26.     CTLWINDOW *ct;
  27.  
  28.     db = wnd->extension;
  29.  
  30.     switch (msg)    {
  31.         case SETFOCUS:
  32.             if (p1)
  33.                 return TRUE;
  34.             break;
  35.         case LEFT_BUTTON:
  36.             if (WindowSizing || WindowMoving)
  37.                 return FALSE;
  38.             if (HitControlBox(wnd, p1-GetLeft(wnd), p2-GetTop(wnd)))    {
  39.                 PostMessage(wnd, KEYBOARD, ' ', ALTKEY);
  40.                 return TRUE;
  41.             }
  42.             ct = db->ctl;
  43.             while (ct->class)    {
  44.                 if (ct->class == RADIOBUTTON)    {
  45.                     int mx = (int) p1 - GetClientLeft(wnd);
  46.                     int my = (int) p2 - GetClientTop(wnd);
  47.                     if (my == ct->dwnd.y && mx == ct->dwnd.x+1)
  48.                         SetRadioButton(wnd, db, ct);
  49.                 }
  50.                 ct++;
  51.             }
  52.             break;
  53.         case PAINT:
  54.             if (!isVisible(wnd))
  55.                 break;
  56.             if (!p2)
  57.                 BaseWndProc(DIALOG, wnd, msg, p1, p2);
  58.             ct = p2 ? (CTLWINDOW *) p2 : db->ctl;
  59.             while (ct->class)    {
  60.                 if (ct->class == RADIOBUTTON)    {
  61.                     char rb[] = "( )";
  62.                     if (ct->itext)
  63.                         rb[1] = 7;
  64.                     SetClassColors(BUTTON);
  65.                     writeline(wnd, rb, ct->dwnd.x, ct->dwnd.y, FALSE);
  66.                 }
  67.                 else if (ct->class == TEXT && ct->vtext != NULL)    {
  68.                     char txt[100];
  69.                     char *cp = ct->vtext;
  70.                     int len = min(ct->dwnd.h, MsgHeight(cp));
  71.                     int i;
  72.                     for (i = 0; i < len; i++)    {
  73.                         int mlen, dif;
  74.                         char *np = strchr(cp, '\n');
  75.                         memset(txt, ' ', sizeof txt);
  76.                          mlen = CopyCommand(txt, cp, FALSE, WndBackground(wnd));
  77.                         if (np == NULL)
  78.                             dif = mlen - strlen(cp);
  79.                         else
  80.                             dif = mlen - (int) (np - cp);
  81.                         txt[ct->dwnd.w + 1 + dif] = '\0';
  82.                         SetStandardColor(wnd);
  83.                         writeline(wnd, txt, ct->dwnd.x, ct->dwnd.y+i, FALSE);
  84.                         if ((cp = strchr(cp, '\n')) != NULL)
  85.                             cp++;
  86.                     }
  87.                 }
  88.                 ct++;
  89.                 if (p2)
  90.                     break;
  91.             }
  92.             return TRUE;
  93.         case KEYBOARD:
  94.             switch ((int)p1)    {
  95.                 case '\t':
  96.                 case ALT_F6:
  97.                     SetNextFocus(inFocus, FALSE);
  98.                     break;
  99.                 case ' ':
  100.                     if ((p2 & ALTKEY) && TestAttribute(wnd, CONTROLBOX))    {
  101.                         wnd->dFocus = inFocus;
  102.                         SysMenuOpen = TRUE;
  103.                         BuildSystemMenu(wnd);
  104.                     }
  105.                     break;
  106.                 case ALT_F4:
  107.                 case ESC:
  108.                     if (!(WindowMoving || WindowSizing))
  109.                         SendMessage(wnd, COMMAND, ID_CANCEL, 0);
  110.                 case UP:
  111.                 case DN:
  112.                 case BS:
  113.                 case FWD:
  114.                 case '\r':
  115.                     if (WindowMoving || WindowSizing)
  116.                         return BaseWndProc(DIALOG, wnd, msg, p1, p2);
  117.                     break;
  118.                 default:
  119.                     /* ------ search all the shortcut keys ----- */
  120.                     dbShortcutKeys(wnd, db, (int) p1);
  121.                     break;
  122.             }
  123.             return TRUE;
  124.         case CLOSE_POPDOWN:
  125.             SysMenuOpen = FALSE;
  126.             break;
  127.         case BUTTON_RELEASED:
  128.             if (!WindowMoving && !WindowSizing)
  129.                 break;
  130.             rtn = BaseWndProc(DIALOG, wnd, msg, p1, p2);
  131.             SendMessage(wnd->dFocus, SETFOCUS, TRUE, 0);
  132.             return rtn;
  133.         case LB_SELECTION:
  134.         case LB_CHOOSE:
  135.             if (SysMenuOpen)
  136.                 return TRUE;
  137.             SendMessage(wnd, COMMAND, inFocusCommand(db), msg);
  138.             break;
  139.         case COMMAND:
  140.             switch ((int) p1)    {
  141.                 case ID_OK:
  142.                 case ID_CANCEL:
  143.                     wnd->ReturnCode = (int) p1;
  144.                     PostMessage(wnd, ENDDIALOG, 0, 0);
  145.                     return TRUE;
  146.                 default:
  147.                     break;
  148.             }
  149.             break;
  150.         case CLOSE_WINDOW:
  151.             if (!p1)
  152.                 SendMessage(wnd, COMMAND, ID_CANCEL, 0);
  153.             else    {
  154.                 ct = db->ctl;
  155.                 while (ct->class)    {
  156.                     if (ct->vtext != NULL && ct->class == TEXT)    {
  157.                         free(ct->vtext);
  158.                         ct->vtext = NULL;
  159.                     }
  160.                     ct++;
  161.                 }
  162.             }
  163.             break;
  164.         default:
  165.             break;
  166.     }
  167.     return BaseWndProc(DIALOG, wnd, msg, p1, p2);
  168. }
  169.  
  170. int DialogBox(WINDOW wnd, DBOX *db,
  171.     int (*wndproc)(struct window *, enum messages, PARAM, PARAM))
  172. {
  173.     int rtn;
  174.     WINDOW Dwnd;
  175.     CTLWINDOW *ct;
  176.     WINDOW oldFocus = inFocus;
  177.     Dwnd = CreateWindow(DIALOG,
  178.                         db->dwnd.title,
  179.                         db->dwnd.x,
  180.                         db->dwnd.y,
  181.                         db->dwnd.h,
  182.                         db->dwnd.w,
  183.                         db,
  184.                         wnd,
  185.                         wndproc,
  186.                         NOCLIP);
  187.     ct = db->ctl;
  188.     while (ct->class)    {
  189.         if (ct->class != TEXT && ct->class != RADIOBUTTON)    {
  190.             WINDOW cwnd;
  191.             int attrib = 0;
  192.             ct->vtext = ct->itext;
  193.             if ((ct->class == EDITBOX || ct->class == LISTBOX)
  194.                     && ct->dwnd.h > 1)
  195.                 attrib |= (MULTILINE | HASBORDER);
  196.             cwnd = CreateWindow(ct->class,
  197.                                 ct->dwnd.title,
  198.                                 ct->dwnd.x+GetClientLeft(Dwnd),
  199.                                 ct->dwnd.y+GetClientTop(Dwnd),
  200.                                 ct->dwnd.h,
  201.                                 ct->dwnd.w,
  202.                                 ct,
  203.                                 Dwnd,
  204.                                 ControlProc,
  205.                                 attrib);
  206.             ct->wnd = cwnd;
  207.             if (Dwnd->dFocus == NULLWND)
  208.                 Dwnd->dFocus = cwnd;
  209.             if (ct->itext)    {
  210.                 char txt[SCREENWIDTH];
  211.                 memset(txt, '\0', sizeof txt);
  212.                  CopyCommand(txt, ct->itext, FALSE, WndBackground(cwnd));
  213.                 SendMessage(cwnd, ADDTEXT, (PARAM) txt, 0);
  214.             }
  215.         }
  216.         else if (ct->class == TEXT && ct->itext != NULL)    {
  217.             int len = strlen(ct->itext)+1;
  218.             ct->vtext = malloc(len);
  219.             strncpy(ct->vtext, ct->itext, len);
  220.         }
  221.         ct++;
  222.     }
  223.     SendMessage(Dwnd->dFocus, SETFOCUS, TRUE, 0);
  224.     SendMessage(Dwnd, SHOW_WINDOW, 0, 0);
  225.     SendMessage(Dwnd, INITIATE_DIALOG, 0, 0);
  226.     SendMessage(Dwnd, CAPTURE_MOUSE, 0, 0);
  227.     SendMessage(Dwnd, CAPTURE_KEYBOARD, 0, 0);
  228.     while (dispatch_message())
  229.         ;
  230.     rtn = Dwnd->ReturnCode == ID_OK;
  231.     SendMessage(Dwnd, RELEASE_MOUSE, 0, 0);
  232.     SendMessage(Dwnd, RELEASE_KEYBOARD, 0, 0);
  233.     SendMessage(Dwnd, CLOSE_WINDOW, TRUE, 0);
  234.     SendMessage(oldFocus, SETFOCUS, TRUE, TRUE);
  235.     return rtn;
  236. }
  237.  
  238. static int inFocusCommand(DBOX *db)
  239. {
  240.     CTLWINDOW *ct = db->ctl;
  241.     while (ct->class)    {
  242.         if (ct->wnd == inFocus)
  243.             return ct->command;
  244.         ct++;
  245.     }
  246.     return -1;
  247. }
  248.  
  249. static CTLWINDOW *FindCommand(DBOX *db, enum commands cmd)
  250. {
  251.     CTLWINDOW *ct = db->ctl;
  252.     while (ct->class)    {
  253.         if (cmd == ct->command)
  254.             return ct;
  255.         ct++;
  256.     }
  257.     return NULL;
  258. }
  259.  
  260. void PushRadioButton(DBOX *db, enum commands cmd)
  261. {
  262.     CTLWINDOW *ct = FindCommand(db, cmd);
  263.     SetRadioButton(NULLWND, db, ct);
  264. }
  265.  
  266. static void SetRadioButton(WINDOW wnd, DBOX *db, CTLWINDOW *ct)
  267. {
  268.     CTLWINDOW *ctt = db->ctl;
  269.     while (ctt->class)    {
  270.         if (ctt->class == RADIOBUTTON)    {
  271.             ctt->itext = OFF;
  272.             if (wnd != NULLWND)
  273.                 SendMessage(wnd, PAINT, 0, (PARAM) ctt);
  274.         }
  275.         ctt++;
  276.     }
  277.     ct->itext = ON;
  278.     if (wnd != NULLWND)    {
  279.         SendMessage(wnd, PAINT, 0, (PARAM) ct);
  280.         PostMessage(GetParent(wnd), COMMAND, ct->command, 0);
  281.     }
  282. }
  283.  
  284. int RadioButtonSetting(DBOX *db, enum commands cmd)
  285. {
  286.     CTLWINDOW *ct = FindCommand(db, cmd);
  287.     if (ct != NULL && ct->class == RADIOBUTTON)
  288.         return (ct->itext != NULL);
  289.     return FALSE;
  290. }
  291.  
  292. void PutItemText(WINDOW wnd, enum commands cmd, char *text)
  293. {
  294.     CTLWINDOW *ct = FindCommand(wnd->extension, cmd);
  295.     if (ct != NULL)        {
  296.         switch (ct->class)    {
  297.             case EDITBOX:
  298.                 SendMessage(ct->wnd, EB_PUTTEXT, (PARAM) text, 0);
  299.                 SendMessage(ct->wnd, PAINT, 0, 0);
  300.                 break;
  301.             case TEXT:    {
  302.                 ct->vtext = realloc(ct->vtext, strlen(text)+1);
  303.                 strcpy(ct->vtext, text);
  304.                 SendMessage(wnd, PAINT, 0, (PARAM) ct);
  305.                 break;
  306.             }
  307.             default:
  308.                 break;
  309.         }
  310.     }
  311. }
  312.  
  313. void GetItemText(WINDOW wnd, enum commands cmd, char *text, int len)
  314. {
  315.     CTLWINDOW *ct = FindCommand(wnd->extension, cmd);
  316.     if (ct != NULL)    {
  317.         switch (ct->class)    {
  318.             case EDITBOX:
  319.                 SendMessage(ct->wnd, EB_GETTEXT, (PARAM) text, len);
  320.                 break;
  321.             case TEXT:
  322.                 strncpy(text, ct->vtext, len);
  323.                 break;
  324.             default:
  325.                 break;
  326.         }
  327.     }
  328. }
  329.  
  330. void GetDlgListText(WINDOW wnd, char *text, enum commands cmd)
  331. {
  332.     CTLWINDOW *ct = FindCommand(wnd->extension, cmd);
  333.     int sel = SendMessage(ct->wnd, LB_CURRENTSELECTION, 0, 0);
  334.     SendMessage(ct->wnd, LB_GETTEXT, (PARAM) text, sel);
  335. }
  336.  
  337. int DlgDirList(WINDOW wnd, char *fspec,
  338.                 enum commands nameid, enum commands pathid,
  339.                 unsigned attrib)
  340. {
  341.     static char drive[MAXDRIVE] = " :";
  342.     static char dir[MAXDIR];
  343.     static char path[MAXPATH];
  344.     static char name[MAXFILE];
  345.     static char ext[MAXEXT];
  346.     int cm;
  347.     int ax, criterr = 1;
  348.     struct ffblk ff;
  349.     CTLWINDOW *ct = FindCommand(wnd->extension, nameid);
  350.     WINDOW lwnd;
  351.  
  352.     cm =
  353. #ifdef MSC
  354.          0;
  355. #endif
  356.     fnsplit(fspec, drive, dir, name, ext);
  357.     *drive = toupper(*drive);
  358.  
  359. #ifdef MSC
  360.     if (*ext)
  361.         cm |= EXTENSION;
  362.     if (*name)
  363.         cm |= FILENAME;
  364.     if (*dir)
  365.         cm |= DIRECTORY;
  366.     if (*drive)
  367.         cm |= DRIVE;
  368. #endif
  369.  
  370.     if (cm & DRIVE)
  371.         setdisk(*drive - 'A');
  372.     if (cm & DIRECTORY)    {
  373.         char *cp = dir+strlen(dir)-1;
  374.         if (*cp == '\\')
  375.             *cp = '\0';
  376.         chdir(dir);
  377.     }
  378.  
  379.     if (!(cm & DRIVE))    {
  380. #ifdef MSC
  381.         _dos_getdrive((unsigned *)drive);
  382.         *drive -= 1;
  383. #else
  384.         *drive = getdisk();
  385. #endif
  386.         *drive += 'A';
  387.     }
  388.  
  389.     getcwd(dir, sizeof dir);
  390.  
  391.     if ((attrib & 0x10) || !(cm & FILENAME))
  392.         strcpy(name, "*");
  393.     if ((attrib & 0x10) || !(cm & EXTENSION))
  394.         strcpy(ext, ".*");
  395.     fnmerge(path, drive, dir+2, name, ext);
  396.  
  397.     if (ct != NULL)    {
  398.  
  399.         lwnd = ct->wnd;
  400.         SendMessage(ct->wnd, CLEARTEXT, 0, 0);
  401.  
  402.         if (attrib & 0x8000)    {
  403.             union REGS regs;
  404.             char drname[15];
  405.             int cd, dr;
  406.  
  407. #ifdef MSC
  408.             _dos_getdrive(&cd);
  409.             cd -= 1;
  410. #else
  411.             cd = getdisk();
  412. #endif
  413.             for (dr = 0; dr < 26; dr++)    {
  414.                 unsigned ndr;
  415.                 setdisk(dr);
  416. #ifdef MSC
  417.                 _dos_getdrive(&ndr);
  418.                 ndr -= 1;
  419. #else
  420.                 ndr = getdisk();
  421. #endif
  422.                 if (ndr == dr)    {
  423.                     /* ------- test for remapped B drive ------- */
  424.                     if (dr == 1)    {
  425.                         regs.x.ax = 0x440e;        /* IOCTL function 14 */
  426.                         regs.h.bl = dr+1;
  427.                         int86(DOS, ®s, ®s);
  428.                         if (regs.h.al != 0)
  429.                             continue;
  430.                     }
  431.  
  432.                     sprintf(drname, "[%c:]", dr+'A');
  433.  
  434.                     /* ------ test for network or RAM disk ---- */
  435.                     regs.x.ax = 0x4409;        /* IOCTL function 9 */
  436.                     regs.h.bl = dr+1;
  437.                     int86(DOS, ®s, ®s);
  438.                     if (!regs.x.cflag)    {
  439.                         if (regs.x.dx & 0x1000)
  440.                             strcat(drname, " (Network)");
  441.                         else if (regs.x.dx == 0x0800)
  442.                             strcat(drname, " (RAMdisk)");
  443.                     }
  444.                     SendMessage(ct->wnd, ADDTEXT, (PARAM) drname, 0);
  445.                 }
  446.             }
  447.             setdisk(cd);
  448.         }
  449.  
  450.         while (criterr == 1)    {
  451.             ax = findfirst(path, &ff, attrib & 0x3f);
  452.             criterr = TestCriticalError();
  453.         }
  454.         if (criterr)
  455.             return FALSE;
  456.         while (ax == 0)    {
  457.             if (!((attrib & 0x4000) &&
  458.                     (ff.ff_attrib & (attrib & 0x3f)) == 0) &&
  459.                         strcmp(ff.ff_name, "."))    {
  460.                 char fname[15];
  461.                 sprintf(fname, (ff.ff_attrib & 0x10) ?
  462.                                 "[%s]" : "%s" , ff.ff_name);
  463.                 SendMessage(ct->wnd, ADDTEXT, (PARAM) fname, 0);
  464.             }
  465.             ax = findnext(&ff);
  466.         }
  467.  
  468.         if (lwnd->wlines > ClientHeight(lwnd))
  469.             AddAttribute(lwnd, VSCROLLBAR);
  470.         else
  471.             ClearAttribute(lwnd, VSCROLLBAR);
  472.         PostMessage(lwnd, SHOW_WINDOW, 0, 0);
  473.     }
  474.  
  475.     if (pathid)    {
  476.         fnmerge(path, drive, dir+2, NULL, NULL);
  477.         PutItemText(wnd, pathid, path);
  478.     }
  479.  
  480.     return TRUE;
  481. }
  482.  
  483. int MsgHeight(char *msg)
  484. {
  485.     int h = 1;
  486.     while ((msg = strchr(msg, '\n')) != NULL)    {
  487.         h++;
  488.         msg++;
  489.     }
  490.     return h;
  491. }
  492.  
  493. int MsgWidth(char *msg)
  494. {
  495.     int w = 0;
  496.     char *cp = msg;
  497.     while ((cp = strchr(msg, '\n')) != NULL)    {
  498.         w = max(w, (int) (cp-msg));
  499.         msg = cp+1;
  500.     }
  501.     return w == 0 ? strlen(msg) : w;
  502. }
  503.  
  504. static void dbShortcutKeys(WINDOW wnd, DBOX *db, int ky)
  505. {
  506.     int i;
  507.     CTLWINDOW *ct;
  508.  
  509.     for (i = 0; i < 36; i++)
  510.         if ((char) ky == altconvert[i])
  511.             break;
  512.     if (i < 36)    {
  513.         ct = db->ctl;
  514.         while (ct->class)    {
  515.             char *cp = ct->vtext;
  516.             while (*cp)    {
  517.                 if (*cp == SHORTCUTCHAR)    {
  518.                     int ch;
  519.                     if (i < 26)
  520.                         ch = 'a' + i;
  521.                     else
  522.                         ch = '0' + i - 26;
  523.                     if (tolower(*(cp+1)) == ch)    {
  524.                         if (ct->class == TEXT)
  525.                             ct++;
  526.                         if (ct->class == RADIOBUTTON)
  527.                             SetRadioButton(wnd, db, ct);
  528.                         else
  529.                             SendMessage(ct->wnd, SETFOCUS, TRUE, 0);
  530.                         return;
  531.                     }
  532.                 }
  533.                 cp++;
  534.             }
  535.             ct++;
  536.         }
  537.     }
  538. }
  539.  
  540. /* generic window processor used by all dialog box control windows */
  541. static int ControlProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  542. {
  543.     DBOX *db = GetParent(wnd)->extension;
  544.     switch (msg)    {
  545.         case KEYBOARD:
  546.             if (GetClass(wnd) == EDITBOX && !isMultiLine(wnd))    {
  547.                 if ((int) p1 == '\r')    {
  548.                     SendMessage(GetParent(wnd), COMMAND, ID_OK, 0);
  549.                     return TRUE;
  550.                 }
  551.             }
  552.             break;
  553.         case SETFOCUS:
  554.             if (GetClass(wnd) != BUTTON)    {
  555.                 if (p1)    {
  556.                     DefaultWndProc(wnd, msg, p1, p2);
  557.                     SendMessage(GetParent(wnd), COMMAND,
  558.                         inFocusCommand(db), ENTERFOCUS);
  559.                     return TRUE;
  560.                 }
  561.                 else 
  562.                     SendMessage(GetParent(wnd), COMMAND,
  563.                         inFocusCommand(db), LEAVEFOCUS);
  564.             }
  565.             break;
  566.         default:
  567.             break;
  568.     }
  569.     return DefaultWndProc(wnd, msg, p1, p2);
  570. }
  571.  
  572.